package it.univaq.mancoosi.injectors.systemconfiguration.managers.ubuntu;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;

import org.eclipse.emf.ecore.util.EcoreUtil;

import it.univaq.mancoosi.injectors.systemconfiguration.managers.LibraryCacheManager;
import it.univaq.mancoosi.mancoosimm.File;
import it.univaq.mancoosi.mancoosimm.Rule;
import it.univaq.mancoosi.mancoosimm.SharedLibrary;

public class UbuntuLibraryCacheManager extends LibraryCacheManager {
	
	protected ArrayList<String> sharedLibraries = new ArrayList<String>();
	
	public UbuntuLibraryCacheManager(){
		super();
	}

	public static LibraryCacheManager getInstance() {
		if (INSTANCE == null)
			INSTANCE = new UbuntuLibraryCacheManager();
		return INSTANCE;
	}
	
	@Override
	public void createLibraryCacheFromSystem() {
		syncSharedLibraryMap();
		
		if(UbuntuEnvironmentManager.getInstance().getEnvironment().getLibraryCache() != null){
			this.libraryCache.getSharedLibraries().addAll(UbuntuEnvironmentManager.getInstance().getEnvironment().getLibraryCache().getSharedLibraries());
		}
		
		SharedLibrary newSharedLibrary;
		ArrayList<String> locations = new ArrayList<String>();
//		locations.add("/home/martina/prova");
		locations.add("/usr/lib");
		locations.add("/lib");
		locations.add("/usr/local/lib");
		
		try{			
			//set locations statically
			for(int i=0; i<locations.size(); i++){
				java.io.File locationsFile = new java.io.File(locations.get(i));
				if(locationsFile.exists()){
					File locationsModelFile = UbuntuFileSystemManager.getInstance()
					.createFile(locations.get(i));
					libraryCache.getLocations().add(locationsModelFile);
				}
				//get sharedLibraries from the File System
				getSharedLibraries(locations.get(i));
			}
			libraryCache.setEnv(UbuntuEnvironmentManager.getInstance().getEnvironment());		
			
			if  (sharedLibraries.size() > 0) {
				for(int i=0; i<sharedLibraries.size(); i++){
					
					java.io.File file = new java.io.File(sharedLibraries.get(i));
					String name = sharedLibraries.get(i).substring(sharedLibraries.get(i).lastIndexOf("/")+1);
					
					if(file.exists()){
						File libraryModelFile = UbuntuFileSystemManager.getInstance().createFile(sharedLibraries.get(i));
						if (!existsSharedLibrary(file.getPath()) || getVersion(name).equals(this.sharedLibraryMap.get(file.getPath()))) {
							newSharedLibrary = factory.createSharedLibrary();
							newSharedLibrary.setLibraryCache(libraryCache);
							
							newSharedLibrary.setName(name);
							newSharedLibrary.setFile(libraryModelFile);

							String version = getVersion(name);
							if(!version.equals("") && !version.equals(".so")){						
								newSharedLibrary.setVersion(version);
							}else{
								newSharedLibrary.setVersion("");
							}
							//add library to libraryCache				
							libraryCache.getSharedLibraries().add(newSharedLibrary);	
						}
					}
				}
			}
			
		}catch (Exception err) {
			err.printStackTrace();
		}
	}
	
	protected String getVersion(String libraryName){
		String version = libraryName.substring(libraryName.lastIndexOf(".so"));
		if(!version.equals("") && version.length()>3){
			version = version.substring(4);
		}
		return version;
	}
	
	
	protected void getSharedLibraries (String dir) {

		java.io.File file = new java.io.File(dir);
		java.io.File[] listFiles = file.listFiles();
		for (java.io.File f : listFiles) {
			if (!f.isDirectory()) {
				if (f.getName().startsWith("lib") && f.getName().contains(".so"))
					sharedLibraries.add(f.getPath());
			}
			else getSharedLibraries(f.getPath());
		}
	}
	
	@Override
	public void synchronize() throws IOException {
		createLibraryCacheFromSystem();
		
		//check whether there have been changes in the number of installed libraries
		int libInTheSystem = sharedLibraries.size();
		
		if(((this.sharedLibraryMap.size()) != libInTheSystem)){		

			Iterator<SharedLibrary> iterator = this.sharedLibraryMap.values().iterator();
			while (iterator.hasNext()) {
				SharedLibrary curr = iterator.next();
				if (isMissingLibraryInTheSystem(curr.getFile().getLocation())) {
					this.sharedLibraryMap.remove(curr);
					EcoreUtil.delete(curr);
					UbuntuFileSystemManager.getInstance().deleteFile(curr.getFile());
				}
			}
		}
	}
	
	public boolean isMissingLibraryInTheSystem (String libraryPath) {
		if(UbuntuFileSystemManager.getInstance().getFile(libraryPath) != null){
			return UbuntuFileSystemManager.getInstance().getFile(libraryPath).isIsMissing();
		}else{
			return true;
		}
//		java.io.File file = new java.io.File(libraryPath);
//		return file.exists();
	}

	@Override
	public Boolean existsSharedLibrary(String sharedLibraryPath) {
		return this.sharedLibraryMap.containsKey(sharedLibraryPath);
	}

}
